package org.yunai.swjg.server.module.skill;

import org.yunai.swjg.server.module.battle.unit.BattleUnit;
import org.yunai.yfserver.enums.IndexedEnum;

import java.util.Comparator;
import java.util.List;

/**
 * 技能定义
 * User: yunai
 * Date: 13-6-11
 * Time: 下午12:40
 */
public interface SkillDef {

    /**
     * 技能类型
     */
    public static enum Type implements IndexedEnum {
        NULL(0),
        STRENGTH_ATTACK(1),
        MAGIC_ATTACK(2),
        STUNT_ATTACK(3),
        TREAT(4),;

        private final int type;

        private Type(int quality) {
            this.type = quality;
        }

        @Override
        public int getIndex() {
            return type;
        }

        private static final List<Type> VALUES = IndexedEnum.Util.toIndexes(values());

        public static Type valueOf(int index) {
            return IndexedEnum.Util.valueOf(VALUES, index);
        }
    }

    /**
     * 效果大类
     */
    public static enum EffectType {
        BUFF_DEBUFF,
        HOT_DOT,
        FUNCTION
    }

    /**
     * 效果枚举
     */
    public static enum Effect implements IndexedEnum {

        // [0001 - 0500] BUFF ========================================

        /**
         * 法术攻击按照百分比上升
         */
        BUFF_MAGIC_ATTACK_ADD_RATE(1, EffectType.BUFF_DEBUFF),
        /**
         * 暴击按照百分比上升
         */
        BUFF_CRIT_ADD_RATE(2, EffectType.BUFF_DEBUFF),
        /**
         * 武力攻击按照百分比上升
         */
        BUFF_STRENGTH_ATTACK_ADD_RATE(3, EffectType.BUFF_DEBUFF),
        /**
         * 武力防御按照百分比上升
         */
        BUFF_STRENGTH_DEFENSE_ADD_RATE(4, EffectType.BUFF_DEBUFF),
        /**
         * 韧性按照百分比上升
         */
        BUFF_TOUGHNESS_ADD_RATE(5, EffectType.BUFF_DEBUFF),
        /**
         * 防御力按照百分比上升
         */
        BUFF_DEFENSE_ALL_ADD_RATE(6, EffectType.BUFF_DEBUFF),
        /**
         * 攻击力按照百分比上升
         */
        BUFF_ATTACK_ALL_ADD_RATE(7, EffectType.BUFF_DEBUFF),
        /**
         * 伤害按照百分比下降
         */
        BUFF_DAMAGE_REDUCE_RATE(8, EffectType.BUFF_DEBUFF),
        /**
         * 绝技防御按照百分比上升
         */
        BUFF_STUNT_DEFENSE_ADD_RATE(9, EffectType.BUFF_DEBUFF),
        /**
         * 绝技防御按照百分比上升
         */
        BUFF_MAGIC_DEFENSE_ADD_RATE(10, EffectType.BUFF_DEBUFF),
        /**
         * 命中按照百分比上升
         */
        BUFF_HIT_ADD_RATE(11, EffectType.BUFF_DEBUFF),
        /**
         * 破击按照百分比上升
         */
        BUFF_POJI_ADD_RATE(12, EffectType.BUFF_DEBUFF),
        /**
         * 必杀按照百分比上升
         */
        BUFF_BISHA_ADD_RATE(13, EffectType.BUFF_DEBUFF),
        /**
         * 闪避按照百分比上升
         */
        BUFF_DODGE_ADD_RATE(14, EffectType.BUFF_DEBUFF),
        /**
         * 格挡按照百分比上升
         */
        BUFF_BLOCK_ADD_RATE(15, EffectType.BUFF_DEBUFF),
        /**
         * 秒杀100%
         */
        BUFF_SEC_KILL_MUST(101, EffectType.BUFF_DEBUFF),
        /**
         * 闪避100%
         */
        BUFF_DODGE_MUST(102, EffectType.BUFF_DEBUFF),
        /**
         * 绝对防御
         */
        BUFF_DEFENSE_ABSOLUTE(103, EffectType.BUFF_DEBUFF),
        /**
         * 隐身
         */
        BUFF_CLOAK(104, EffectType.BUFF_DEBUFF),
        /**
         * 必中
         */
        BUFF_HIT_MUST(105, EffectType.BUFF_DEBUFF),
        /**
         * 绝技攻击按照百分比上升
         */
        BUFF_STUNT_ATTACK_ADD_RATE(106, EffectType.BUFF_DEBUFF),

        // [0501 - 1000] DEBUFF ========================================
        /**
         * 晕眩
         */
        DEBUFF_STUN(501, EffectType.BUFF_DEBUFF),
        /**
         * 所有防御变成0
         */
        DEBUFF_DEFENSE_ALL_ZERO(502, EffectType.BUFF_DEBUFF),
        /**
         * 无法获得士气
         */
        DEBUFF_MORALE_CANNOT_GET(503, EffectType.BUFF_DEBUFF),
        // empty 504
        /**
         * 睡眠
         */
        DEBUFF_SLEEP(505, EffectType.BUFF_DEBUFF),
        /**
         * 命中变成0
         */
        DEBUFF_HIT_ZERO(506, EffectType.BUFF_DEBUFF),
        /**
         * 普通攻击力按照百分比下降
         */
        DEBUFF_STRENGTH_ATTACK_REDUCE_RATE(0507, EffectType.BUFF_DEBUFF),
        /**
         * 混乱
         */
        DEBUFF_CHAOS(508, EffectType.BUFF_DEBUFF),
        /**
         * 所有攻击力降低，按照百分比
         */
        DEBUFF_ATTACK_ALL_REDUCE_RATE(509, EffectType.BUFF_DEBUFF),
        /**
         * 沉默
         */
        DEBUFF_SILENT(510, EffectType.BUFF_DEBUFF),
        /**
         * 所有防御力降低，按照百分比
         */
        DEBUFF_DEFENSE_ALL_REDUCE_RATE(511, EffectType.BUFF_DEBUFF),
        /**
         * 绝技攻击按照百分比下降
         */
        DEBUFF_STUNT_ATTACK_REDUCE_RATE(512, EffectType.BUFF_DEBUFF),
        /**
         * 法术攻击按照百分比下降
         */
        DEBUFF_MAGIC_ATTACK_REDUCE_RATE(513, EffectType.BUFF_DEBUFF),
        /**
         * 普通防御按照百分比下降
         */
        DEBUFF_STRENGTH_DEFENSE_REDUCE_RATE(514, EffectType.BUFF_DEBUFF),
        /**
         * 绝技防御按照百分比下降
         */
        DEBUFF_STUNT_DEFENSE_REDUCE_RATE(515, EffectType.BUFF_DEBUFF),
        /**
         * 法术防御按照百分比下降
         */
        DEBUFF_MAGIC_DEFENSE_REDUCE_RATE(516, EffectType.BUFF_DEBUFF),
        /**
         * 暴击按照百分比下降
         */
        DEBUFF_CRIT_REDUCE_RATE(517, EffectType.BUFF_DEBUFF),
        /**
         * 命中按照百分比下降
         */
        DEBUFF_HIT_REDUCE_RATE(518, EffectType.BUFF_DEBUFF),
        /**
         * 破击按照百分比下降
         */
        DEBUFF_POJI_REDUCE_RATE(519, EffectType.BUFF_DEBUFF),
        /**
         * 必杀按照百分比下降
         */
        DEBUFF_BISHA_REDUCE_RATE(520, EffectType.BUFF_DEBUFF),
        /**
         * 韧性按照百分比下降
         */
        DEBUFF_TOUGHNESS_REDUCE_RATE(521, EffectType.BUFF_DEBUFF),
        /**
         * 闪避按照百分比下降
         */
        DEBUFF_DODGE_REDUCE_RATE(522, EffectType.BUFF_DEBUFF),
        /**
         * 格挡按照百分比下降
         */
        DEBUFF_BLOCK_REDUCE_RATE(523, EffectType.BUFF_DEBUFF),

        // [1001 - 1500] HOT ========================================

        /**
         * 持续减血，按照HP百分比
         */
        DOT_HP_REDUCE_RATE(1001, EffectType.HOT_DOT),
        /**
         * 持续加血，按照HP百分比
         */
        HOT_HP_ADD_RATE(1002, EffectType.HOT_DOT),


        // [1501 - 2000] DOT ========================================

        // [2001 - 2500] FUNCTION ========================================
        /**
         * 士气增加
         */
        FUNCTION_MORALE_ADD(2001, EffectType.FUNCTION),
        /**
         * 士气归0
         */
        FUNCTION_MORALE_ZERO(2002, EffectType.FUNCTION),
        /**
         * 吸血，按照输出百分比
         */
        FUNCTION_SUCK_BLOOD(2003, EffectType.FUNCTION),
        /**
         * 换命
         */
        FUNCTION_SWAP_HP(2004, EffectType.FUNCTION),
        /**
         * 士气降低
         */
        FUNCTION_MORALE_REDUCE(2005, EffectType.FUNCTION);

        private final int sn;
        private final EffectType type;

        private Effect(int id, EffectType type) {
            this.sn = id;
            this.type = type;
        }

        @Override
        public int getIndex() {
            return sn;
        }

        public EffectType getType() {
            return type;
        }

        private static final List<Effect> VALUES = IndexedEnum.Util.toIndexes(values());

        public static Effect valueOf(int sn) {
            return IndexedEnum.Util.valueOf(VALUES, sn);
        }
    }

    /**
     * 攻击范围
     */
    public static enum Scope implements IndexedEnum {
        /**
         * 行
         */
        HANG(1),
        /**
         * 列
         */
        LIE(2),
        /**
         * 全体
         */
        ALL(3),
        /**
         * 目标周围，半径为1
         * TODO 暂时不实现
         */
        ROUND(4)
        ;

        private final int scope;

        private Scope(int scope) {
            this.scope = scope;
        }

        @Override
        public int getIndex() {
            return scope;
        }

        private static final List<Scope> VALUES = IndexedEnum.Util.toIndexes(values());

        public static Scope valueOf(int index) {
            return IndexedEnum.Util.valueOf(VALUES, index);
        }
    }

    /**
     * 攻击目标
     */
    public static enum Target implements IndexedEnum {
        /**
         * 敌人
         */
        ENEMY(1),
        /**
         * 队友
         */
        TEAM(3),
        /**
         * 自己
         */
        SELF(5),
        /**
         * 无目标
         */
        NONE(7)
        ;

        static {
            ENEMY.chaosTarget = TEAM;
            TEAM.chaosTarget = ENEMY;
            SELF.chaosTarget = NONE;
            NONE.chaosTarget = NONE;
        }

        private final int target;
        /**
         * 混乱时的目标
         */
        private Target chaosTarget;

        private Target(int target) {
            this.target = target;
        }

        @Override
        public int getIndex() {
            return target;
        }

        public Target getChaosTarget() {
            return chaosTarget;
        }

        private static final List<Target> VALUES = IndexedEnum.Util.toIndexes(values());

        public static Target valueOf(int index) {
            return IndexedEnum.Util.valueOf(VALUES, index);
        }
    }

    /**
     * 查询目标顺序
     */
    public static enum TargetSort implements IndexedEnum {
        /**
         * 正序
         */
        INDEX_ASC(1, new Comparator<BattleUnit>() {
            @Override
            public int compare(BattleUnit o1, BattleUnit o2) {
                int a = o1.getUnitIndex();
                int b = o2.getUnitIndex();
                return a > b ? 1 : a == b ? 0 : -1;
            }
        }),
        /**
         * 倒序
         */
        INDEX_DESC(2, new Comparator<BattleUnit>() {
            @Override
            public int compare(BattleUnit o1, BattleUnit o2) {
                int a = o1.getUnitIndex();
                int b = o2.getUnitIndex();
                return a > b ? -1 : a == b ? 0 : 1;
            }
        }),
        /**
         * 下一个
         */
        NEXT(3, new Comparator<BattleUnit>() {
            @Override
            public int compare(BattleUnit o1, BattleUnit o2) {
                int a = o1.getUnitIndex();
                int b = o2.getUnitIndex();
                return a > b ? 1 : a == b ? 0 : -1;
            }
        }),
        /**
         * 士气下降
         */
        MORALE_DESC(4, new Comparator<BattleUnit>() {
            @Override
            public int compare(BattleUnit o1, BattleUnit o2) {
                int a = o1.getMoraleCur();
                int b = o2.getMoraleCur();
                return a > b ? -1 : a == b ? 0 : 1;
            }
        }),
        /**
         * 随机
         */
        RANDOM(5, null),
        /**
         * 血量上升
         */
        HP_ASC(6, new Comparator<BattleUnit>() {
            @Override
            public int compare(BattleUnit o1, BattleUnit o2) {
                int a = o1.getHpCur();
                int b = o2.getHpCur();
                return a > b ? 1 : a == b ? 0 : -1;
            }
        });

        private final int sort;
        private final Comparator<BattleUnit> comparator;

        private TargetSort(int sort, Comparator<BattleUnit> comparable) {
            this.sort = sort;
            this.comparator = comparable;
        }

        @Override
        public int getIndex() {
            return sort;
        }

        public Comparator<BattleUnit> getComparator() {
            return comparator;
        }

        private static final List<TargetSort> VALUES = IndexedEnum.Util.toIndexes(values());

        public static TargetSort valueOf(int index) {
            return IndexedEnum.Util.valueOf(VALUES, index);
        }
    }

    /**
     * 技能影响效果发生时刻
     */
    public static enum ImpactTime implements IndexedEnum {
        /**
         * 攻击前
         */
        BEFORE_ATTACK(1),
        /**
         * 攻击后
         */
        AFTER_ATTACK(2);

        private int time;

        private ImpactTime(int time) {
            this.time = time;
        }

        @Override
        public int getIndex() {
            return time;
        }

        private static final List<ImpactTime> VALUES = IndexedEnum.Util.toIndexes(values());

        public static ImpactTime valueOf(int index) {
            return IndexedEnum.Util.valueOf(VALUES, index);
        }
    }

    /**
     * 技能影响效果目标
     */
    public static enum ImpactTarget implements IndexedEnum {
        /**
         * 技能目标
         */
        SKILL_TARGET(1),
        /**
         * 自己
         */
        SELF(2),
        /**
         * 士气最高，较为特殊
         * TODO 暂时不实现
         */
        MORALE_MAX(3);

        private final int target;

        private ImpactTarget(int target) {
            this.target = target;
        }

        @Override
        public int getIndex() {
            return target;
        }

        private static final List<ImpactTarget> VALUES = IndexedEnum.Util.toIndexes(values());

        public static ImpactTarget valueOf(int index) {
            return IndexedEnum.Util.valueOf(VALUES, index);
        }
    }
}
